package com.ruis.kotboot.common.plug;

import com.alibaba.fastjson.JSON;
import okhttp3.*;

import java.net.URLEncoder;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class HttpUtils {
    private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");//mdiatype 这个需要和服务端保持一致
    private static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");//mdiatype 这个需要和服务端保持一致

    public static final int TYPE_GET = 0;//get请求
    public static final int TYPE_POST_JSON = 1;//post请求参数为json
    public static final int TYPE_POST_FORM = 2;//post请求参数为表单

    public static OkHttpClient getClient() {
        //初始化OkHttpClient
        return new OkHttpClient().newBuilder()
                .connectTimeout(5, TimeUnit.SECONDS)//设置超时时间
                .readTimeout(5, TimeUnit.SECONDS)//设置读取超时时间
                .writeTimeout(5, TimeUnit.SECONDS)//设置写入超时时间
                .build();
    }

    /**
     *  okHttp同步请求统一入口
     * @param actionUrl  接口地址
     * @param requestType 请求类型
     * @param paramsMap   请求参数
     */
    public static Response requestSyn(int requestType, String actionUrl, Map<String, String> paramsMap) {
        Response response=null;
        switch (requestType) {
            case TYPE_GET:
                response=requestGetBySyn(actionUrl, paramsMap);
                break;
            case TYPE_POST_JSON:
                response=requestPostBySyn(actionUrl, paramsMap);
                break;
            case TYPE_POST_FORM:
                response=requestPostBySynWithForm(actionUrl, paramsMap);
                break;
        }
        return response;
    }

    /**
     * okHttp get同步请求
     * @param actionUrl  接口地址
     * @param paramsMap   请求参数
     */
    private static Response requestGetBySyn(String actionUrl, Map<String, String> paramsMap) {
        StringBuilder tempParams = new StringBuilder();
        try {
            //处理参数
            int pos = 0;
            for (String key : paramsMap.keySet()) {
                if (pos > 0) {
                    tempParams.append("&");
                }
                //对参数进行URLEncoder
                tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
                pos++;
            }
            //补全请求地址
            String requestUrl = String.format("%s?%s", actionUrl, tempParams.toString());
            //创建一个请求
            Request request = addHeaders().url(requestUrl).build();
            //创建一个Call
            final Call call = getClient().newCall(request);
            //执行请求
            final Response response = call.execute();
            return response;
            //response.body().string();
        } catch (Exception e) { }
        return null;
    }

    /**
     * okHttp post同步请求
     * @param requestUrl  接口地址
     * @param paramsMap   请求参数
     */
    private static Response requestPostBySyn(String requestUrl, Map<String, String> paramsMap) {
        try {
            //生成参数
            String params = JSON.toJSONString(paramsMap);
            //创建一个请求实体对象 RequestBody
            RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, params);
            //创建一个请求
            final Request request = addHeaders().url(requestUrl).post(body).build();
            //创建一个Call
            final Call call = getClient().newCall(request);
            //执行请求
            Response response = call.execute();
            //请求执行成功
            return response;
            //response.body().string();
        } catch (Exception e) {}
        return null;
    }

    /**
     * okHttp post同步请求表单提交
     * @param requestUrl 接口地址
     * @param paramsMap 请求参数
     */
    private static Response requestPostBySynWithForm(String requestUrl, Map<String, String> paramsMap) {
        try {
            //创建一个FormBody.Builder
            FormBody.Builder builder = new FormBody.Builder();
            for (String key : paramsMap.keySet()) {
                //追加表单信息
                builder.add(key, paramsMap.get(key));
            }
            //生成表单实体对象
            RequestBody formBody = builder.build();
            //创建一个请求
            final Request request = addHeaders().url(requestUrl).post(formBody).build();
            //创建一个Call
            final Call call = getClient().newCall(request);
            //执行请求
            Response response = call.execute();
            //请求执行成功
            return response;
            //response.body().string();
        } catch (Exception e) {}
        return null;
    }

    /**
     * okHttp异步请求统一入口
     * @param actionUrl   接口地址
     * @param requestType 请求类型
     * @param paramsMap   请求参数
     * @param callBack 请求返回数据回调
     **/
    public static Call requestAsyn(int requestType, String actionUrl, Map<String, String> paramsMap, Callback callBack) {
        Call call = null;
        switch (requestType) {
            case TYPE_GET:
                call = requestGetByAsyn(actionUrl, paramsMap, callBack);
                break;
            case TYPE_POST_JSON:
                call = requestPostByAsyn(actionUrl, paramsMap, callBack);
                break;
            case TYPE_POST_FORM:
                call = requestPostByAsynWithForm(actionUrl, paramsMap, callBack);
                break;
        }
        return call;
    }

    /**
     * okHttp get异步请求
     * @param actionUrl 接口地址
     * @param paramsMap 请求参数
     * @param callBack 请求返回数据回调
     * @return
     */
    private static Call requestGetByAsyn(String actionUrl, Map<String, String> paramsMap, final Callback callBack) {
        StringBuilder tempParams = new StringBuilder();
        try {
            int pos = 0;
            for (String key : paramsMap.keySet()) {
                if (pos > 0) {
                    tempParams.append("&");
                }
                tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
                pos++;
            }
            String requestUrl = String.format("%s?%s", actionUrl, tempParams.toString());
            final Request request = addHeaders().url(requestUrl).build();
            final Call call = getClient().newCall(request);
            call.enqueue(callBack);
            return call;
        } catch (Exception e) {}
        return null;
    }

    /**
     * okHttp post异步请求
     * @param requestUrl 接口地址
     * @param paramsMap 请求参数
     * @param callBack 请求返回数据回调
     * @return
     */
    private static Call requestPostByAsyn(String requestUrl, Map<String, String> paramsMap, final Callback callBack) {
        try {
            StringBuilder tempParams = new StringBuilder();
            int pos = 0;
            for (String key : paramsMap.keySet()) {
                if (pos > 0) {
                    tempParams.append("&");
                }
                tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
                pos++;
            }
            String params = tempParams.toString();
            RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, params);
            final Request request = addHeaders().url(requestUrl).post(body).build();
            final Call call = getClient().newCall(request);
            call.enqueue(callBack);
            return call;
        } catch (Exception e) { }
        return null;
    }

    /**
     * okHttp post异步请求表单提交
     * @param requestUrl 接口地址
     * @param paramsMap 请求参数
     * @param callBack 请求返回数据回调
     * @return
     */
    private static Call requestPostByAsynWithForm(String requestUrl, Map<String, String> paramsMap, final Callback callBack) {
        try {
            FormBody.Builder builder = new FormBody.Builder();
            for (String key : paramsMap.keySet()) {
                builder.add(key, paramsMap.get(key));
            }
            RequestBody formBody = builder.build();
            final Request request = addHeaders().url(requestUrl).post(formBody).build();
            final Call call = getClient().newCall(request);
            call.enqueue(callBack);
            return call;
        } catch (Exception e) {}
        return null;
    }







    /**
     * 统一为请求添加头信息
     * @return
     */
    private static Request.Builder addHeaders() {
        Request.Builder builder = new Request.Builder()
                .addHeader("Connection", "keep-alive");
        return builder;
    }
}
